package com.wf.classRoomTest.server;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.atomic.AtomicInteger;

public class Demo {

    static class SumTask implements Runnable {
        private final int[] ints;
        private final int start;
        private final int end;
        private final AtomicInteger partialSum;
        private final CyclicBarrier barrier;

        public SumTask(int[] ints, int start, int end, AtomicInteger partialSum, CyclicBarrier barrier) {
            this.ints = ints;
            this.start = start;
            this.end = end;
            this.partialSum = partialSum;
            this.barrier = barrier;
        }

        @Override
        public void run() {
            int localSum = 0;
            for (int i = start; i < end; i++) {
                localSum += ints[i];
            }
            partialSum.addAndGet(localSum);
            try {
                barrier.await();
            } catch (InterruptedException | BrokenBarrierException e) {
                Thread.currentThread().interrupt();
                throw new RuntimeException(e);
            }
        }
    }

    public static void main(String[] args) {
        int[] ints = new int[1000];
        for (int i = 0; i < ints.length; i++) {
            ints[i] = (int) (Math.random() * 100);
        }

        int sumSingleThread = 0;
        for (int anInt : ints) {
            sumSingleThread += anInt;
        }
        System.out.println("单线程下1000个数字的总和: " + sumSingleThread);

        AtomicInteger[] partialSums = new AtomicInteger[5];
        for (int i = 0; i < partialSums.length; i++) {
            partialSums[i] = new AtomicInteger(0);
        }

        CyclicBarrier barrier = new CyclicBarrier(5, () -> {
            int totalSum = 0;
            for (AtomicInteger sum : partialSums) {
                totalSum += sum.get();
            }
            System.out.println("多线程计算结果: " + totalSum);
        });

        Thread[] threads = new Thread[5];
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(new SumTask(ints, i * 200, (i + 1) * 200, partialSums[i], barrier));
            threads[i].start();
        }

        for (Thread thread : threads) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new RuntimeException(e);
            }
        }
    }
}
